package vn.edu.ptithcm.pim.util;

import java.awt.Color;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import vn.edu.ptithcm.pim.dom.Task;

import com.lowagie.text.Chunk;
import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.Element;
import com.lowagie.text.Font;
import com.lowagie.text.FontFactory;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.PdfPCell;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

public class FileUtil {
	static Logger log = Logger.getLogger(FileUtil.class);

	public static String transferTo(MultipartFile multipartFile,
			String rootPath, String folder) throws IllegalStateException,
			IOException {
		StringBuilder pathToFile = new StringBuilder();
		if (multipartFile.getSize() > 0) {
			int index = StringUtils.indexOf(rootPath, "pim");
			rootPath = rootPath.substring(0, index) + folder + "\\";
			StringBuilder fileName = new StringBuilder();
			fileName.append(multipartFile.getOriginalFilename());
			multipartFile.transferTo(new File(new File(rootPath), fileName
					.toString()));
			pathToFile.append("/").append(folder).append("/").append(fileName);
		}
		return pathToFile.toString();
	}

	public static String transferTo(HttpServletRequest request, String param,
			String folder) throws IllegalStateException, IOException {
		StringBuilder pathToFile = new StringBuilder();

		if (request instanceof MultipartHttpServletRequest) {
			MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
			MultipartFile multipartFile = multipartRequest.getFile(param);

			if (multipartFile.getSize() > 0) {
				String path = request.getSession().getServletContext()
						.getRealPath("");
				int index = StringUtils.indexOf(path, "pim");
				path = path.substring(0, index) + folder + "\\";

				StringBuilder fileName = new StringBuilder();
				fileName.append("_").append(System.currentTimeMillis())
						.append(multipartFile.getOriginalFilename());

				multipartFile.transferTo(new File(new File(path), fileName
						.toString()));

				pathToFile.append("/").append(folder).append("/")
						.append(fileName);
			}
		}
		return pathToFile.toString();
	}

	@SuppressWarnings("unchecked")
	public static String transferTo(HttpServletRequest request, String folder)
			throws Exception {
		StringBuilder pathToFile = new StringBuilder();

		if (ServletFileUpload.isMultipartContent(request)) {
			String path = request.getSession().getServletContext()
					.getRealPath("");
			int index = StringUtils.indexOf(path, "pim");
			path = path.substring(0, index) + folder + "\\";

			List<FileItem> files = new ServletFileUpload(
					new DiskFileItemFactory()).parseRequest(request);
			log.info(files.size());

			for (FileItem file : files) {
				if (!file.isFormField()) {
					if (file.getSize() > 0) {
						StringBuilder fileName = new StringBuilder();
						fileName.append("_").append(System.currentTimeMillis())
								.append(file.getName());

						pathToFile.append(file.getName()).append(",")
								.append("/").append(folder).append("/")
								.append(fileName.toString());

						File saveFile = new File(path + fileName.toString());
						file.write(saveFile);
					}
				}
			}
		}
		return pathToFile.toString();
	}

	public static String generateTaskReport(HttpServletRequest request,
			HttpServletResponse response, Task task, String folder)
			throws FileNotFoundException, DocumentException {
		String rootPath = request.getSession().getServletContext()
				.getRealPath("");
		int index = StringUtils.indexOf(rootPath, "pim");
		rootPath = rootPath.substring(0, index) + folder;
		String fileName = task.getProject().getName() + "-" + task.getCode()
				+ ".pdf";

		Document document = new Document(PageSize.A4, 20, 20, 20, 20);

		PdfWriter.getInstance(document, new FileOutputStream(rootPath + "\\"
				+ fileName));

		document.open();

		StringBuilder s = new StringBuilder();
		s.append("[").append(task.getProject().getName()).append(" - ")
				.append(task.getTaskCategory().getName()).append(" #")
				.append(task.getCode()).append("]").append(" (")
				.append(task.getTaskStatus().getName()).append(") ")
				.append(task.getSummary());

		Paragraph header = new Paragraph(s.toString(), FontFactory.getFont(
				FontFactory.TIMES_ROMAN, 14, Font.BOLD, Color.BLACK));
		header.setAlignment(Element.ALIGN_CENTER);
		document.add(header);

		addEmptyLine(document, 2);

		PdfPTable table = new PdfPTable(5);

		PdfPCell c1 = new PdfPCell(new Phrase("ID"));
		c1.setHorizontalAlignment(Element.ALIGN_CENTER);
		c1.setPadding(5.0f);
		table.addCell(c1);

		c1 = new PdfPCell(new Phrase("Category"));
		c1.setHorizontalAlignment(Element.ALIGN_CENTER);

		c1.setPadding(5.0f);
		table.addCell(c1);

		c1 = new PdfPCell(new Phrase("Severity"));
		c1.setHorizontalAlignment(Element.ALIGN_CENTER);

		c1.setPadding(5.0f);
		table.addCell(c1);

		c1 = new PdfPCell(new Phrase("Priority"));
		c1.setHorizontalAlignment(Element.ALIGN_CENTER);

		c1.setPadding(5.0f);
		table.addCell(c1);

		c1 = new PdfPCell(new Phrase("Last Update"));
		c1.setHorizontalAlignment(Element.ALIGN_CENTER);
		c1.setPadding(5.0f);
		table.addCell(c1);
		table.setHeaderRows(1);

		table.addCell(task.getCode());
		table.addCell(task.getTaskCategory().getName());
		table.addCell(task.getTaskSeverity().getName());
		table.addCell(task.getTaskPriority().getName());
		table.addCell(DateTimeUtil.dateToString(task.getLastchanged(),
				"yyyy-MM-dd hh:mm"));

		c1 = new PdfPCell(new Phrase("Status"));
		c1.setHorizontalAlignment(Element.ALIGN_LEFT);

		c1.setPadding(5.0f);
		table.addCell(c1);
		table.setHeaderRows(1);

		c1 = new PdfPCell(new Phrase(task.getTaskStatus().getName()));
		c1.setColspan(4);
		table.addCell(c1);

		c1 = new PdfPCell(new Phrase("Percent completed"));
		c1.setHorizontalAlignment(Element.ALIGN_LEFT);

		c1.setPadding(5.0f);
		table.addCell(c1);
		table.setHeaderRows(1);

		c1 = new PdfPCell(new Phrase(task.getPercentcomplete() != null ? task
				.getPercentcomplete().toString() : ""));
		c1.setColspan(4);
		table.addCell(c1);

		c1 = new PdfPCell(new Phrase("Phase"));
		c1.setHorizontalAlignment(Element.ALIGN_LEFT);

		c1.setPadding(5.0f);
		table.addCell(c1);
		table.setHeaderRows(1);

		c1 = new PdfPCell(new Phrase(task.getPhase() != null ? task.getPhase()
				: ""));
		c1.setColspan(4);
		table.addCell(c1);

		c1 = new PdfPCell(new Phrase("Actual hours"));
		c1.setHorizontalAlignment(Element.ALIGN_LEFT);

		c1.setPadding(5.0f);
		table.addCell(c1);
		table.setHeaderRows(1);

		c1 = new PdfPCell(new Phrase(task.getActualtime() != null ? task
				.getActualtime().toString() : ""));
		c1.setColspan(4);
		table.addCell(c1);

		c1 = new PdfPCell(new Phrase("Estimate hours"));
		c1.setHorizontalAlignment(Element.ALIGN_LEFT);

		c1.setPadding(5.0f);
		table.addCell(c1);
		table.setHeaderRows(1);

		c1 = new PdfPCell(new Phrase(task.getEstimatetime() != null ? task
				.getEstimatetime().toString() : ""));
		c1.setColspan(4);
		table.addCell(c1);

		c1 = new PdfPCell(new Phrase("Start time"));
		c1.setHorizontalAlignment(Element.ALIGN_LEFT);

		c1.setPadding(5.0f);
		table.addCell(c1);
		table.setHeaderRows(1);

		c1 = new PdfPCell(new Phrase(DateTimeUtil.dateToString(
				task.getStarttime(), "yyyy-MM-dd")));
		c1.setColspan(4);
		table.addCell(c1);

		c1 = new PdfPCell(new Phrase("End time"));
		c1.setHorizontalAlignment(Element.ALIGN_LEFT);

		c1.setPadding(5.0f);
		table.addCell(c1);
		table.setHeaderRows(1);

		c1 = new PdfPCell(new Phrase(DateTimeUtil.dateToString(
				task.getEndtime(), "yyyy-MM-dd")));
		c1.setColspan(4);
		table.addCell(c1);

		document.add(table);

		addEmptyLine(document, 1);

		document.add(new Chunk("Summary : "));
		Paragraph summary = new Paragraph(task.getSummary(),
				FontFactory.getFont(FontFactory.TIMES_ROMAN, 13, Font.ITALIC,
						Color.BLACK));
		summary.setIndentationLeft(10.0f);
		document.add(summary);

		document.add(new Chunk("Description : "));
		Paragraph description = new Paragraph(task.getSummary(),
				FontFactory.getFont(FontFactory.TIMES_ROMAN, 13, Font.ITALIC,
						Color.BLACK));
		description.setIndentationLeft(10.0f);
		document.add(description);

		document.add(new Chunk("Additional information : "));
		Paragraph additionalInformation = new Paragraph(
				task.getAdditionalinformation(), FontFactory.getFont(
						FontFactory.TIMES_ROMAN, 13, Font.ITALIC, Color.BLACK));
		additionalInformation.setIndentationLeft(10.0f);
		document.add(additionalInformation);

		document.add(new Chunk("Note : "));
		Paragraph note = new Paragraph(task.getNote(), FontFactory.getFont(
				FontFactory.TIMES_ROMAN, 13, Font.ITALIC, Color.BLACK));
		note.setIndentationLeft(10.0f);
		document.add(note);

		addEmptyLine(document, 2);

		document.add(new Phrase("Reporter"));

		c1 = new PdfPCell(new Phrase("Assigned to"));
		c1.setPaddingLeft(50.0f);
		c1.setPaddingRight(50.0f);
		document.add(c1);

		document.add(new Phrase("Monitored by"));

		addEmptyLine(document, 1);

		document.add(new Phrase(task.getReporter()));

		c1 = new PdfPCell(new Phrase(task.getAssignedto()));
		c1.setPaddingLeft(50.0f);
		c1.setPaddingRight(50.0f);
		document.add(c1);

		document.add(new Phrase(task.getMonitoredby()));

		document.close();
		return rootPath + "\\" + fileName;
	}

	private static void addEmptyLine(Document document, int number) {
		for (int i = 0; i < number; i++) {
			try {
				document.add(new Paragraph(" "));
			} catch (DocumentException e) {
				e.printStackTrace();
			}
		}
	}

	public static float getSizeInKByte(String documentPath) {
		try {
			File file = FileUtils.getFile(documentPath);
			return (float) (1.0 * file.length() / 1024);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return 0;
	}

	public static boolean deleteFile(String path) {
		boolean success = true;
		try {
			File f = new File(path);
			success = f.delete();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return success;
	}
}
